/*************************************************************************
	Message Layer
 
 	create and delete Controls, set options by string
*************************************************************************/

using UnityEngine;
using System;
using System.Collections.Generic;

[Serializable]
public class UKagMessageLayer_SaveData : UTVPMessageLayer_SaveData
{
	public UKagMessageLayer_SaveData() {}
	
	public int ChWaits;
	public int LineWaits;
	public int PageWaits;
}

//[RequireComponent(typeof(MeshCollider))]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class UKagMessageLayer : UTVPMessageLayer
{
	public int ChWaits = 50;
	public int LineWaits = 300;
	public int PageWaits = 1000;

	protected Dictionary<string, UKagControlBase> m_Controls = new Dictionary<string, UKagControlBase>();
	public Dictionary<string, UKagControlBase> Controls { get { return m_Controls; } }
	private List<string> m_ControlKeys = new List<string>();
	
	protected UTVPMessageLayer m_NameLayer = null;
	public UTVPMessageLayer NameLayer { get { return m_NameLayer; } }
	protected string[] m_NameList = null;
	protected string m_NameImgSeq = null;
	protected UTVPAnimationLayer m_NameImgLayer = null;
	protected UTVPAnimationLayer m_FaceLayer = null;
	public UTVPAnimationLayer FaceLayer { get { return m_FaceLayer; } }
	
	protected override void Awake()
	{
		base.Awake();
		
		m_Controls.Clear();
	}

	protected override void Init(UTVPSystem system, UTVPAnimationLayer glyph, int charBufferLength)
	{
		base.Init(system, glyph, charBufferLength);

		UKagSystem kagSystem = system as UKagSystem;
		if (kagSystem != null)
		{
			LineBreakMode = kagSystem.LineBreakMode;
			ChWaits = kagSystem.ChWaits;
			LineWaits = kagSystem.LineWaits;
			PageWaits = kagSystem.PageWaits;
		}
	}
	
	public override void RefreshVisibleState()
	{
		base.RefreshVisibleState();
		FocusedControl = null;
	}

	public void SetAlphabeticWord(List<UKagScenarioTag> tagList, int startIdx)
	{
		m_CurrAlphabeticWord.Clear();
		for (int i=startIdx; i<tagList.Count; i++)
		{
			if (tagList[i].name != "ch")
				break;
			string text = tagList[i].GetParamValue("text");
			for (int j=0; j<text.Length; j++)
			{
				if (text[j] == ' ')
					return;
				m_CurrAlphabeticWord.Add(text[j]);
			}
		}
	}
	
	public T CreateControl<T>(string name, int index) where T : UKagControlBase
	{
		T control = UKagControlBase.CreateControl<T>(m_System, this, name, this.gameObject.layer);
		control.tabIdx = index;
		control.layer.AbsoluteIndex = index;
		m_Controls[name] = control;
		return control;
	}
	
	public bool DeleteControl(string name)
	{
		if (m_Controls.ContainsKey(name))
		{
			Destroy(m_Controls[name].gameObject);
			m_Controls.Remove(name);
			return true;
		}
		else
			return false;
	}
	public void ClearControls(bool all)
	{
		if (m_Controls.Count == 0)
			return;
		
		m_ControlKeys.Clear();
		m_ControlKeys.AddRange(m_Controls.Keys);
		for (int i=0; i<m_ControlKeys.Count; i++)
		{
			string key = m_ControlKeys[i];
			if (all || !m_Controls[key].isSys)
			{
				Destroy(m_Controls[key].gameObject);
				m_Controls.Remove(key);
			}
		}
	}
	
	private UKagControlBase m_FocusedControl = null;
	public UKagControlBase FocusedControl
	{
		get { return m_FocusedControl; }
		set
		{
			if (m_FocusedControl == value)
				return;
			m_FocusedControl = value;
			foreach (UKagControlBase ctl in m_Controls.Values)
			{
				if (ctl == m_FocusedControl)
					ctl.focus = true;
				else
					ctl.focus = false;
			}
		}
	}
	
	public void RefreshRadioButtonState(UKagButton selectedBtn)
	{
		if (selectedBtn.type != UKagButton.BUTTON_TYPE.RADIO || !selectedBtn.selected)
			return;
		
		foreach (UKagControlBase ctl in m_Controls.Values)
		{
			if (ctl is UKagButton)
			{
				UKagButton btn = ctl as UKagButton;
				if (btn.type == UKagButton.BUTTON_TYPE.RADIO
					&& btn.RadioButtonGroup == selectedBtn.RadioButtonGroup
					&& btn.name != selectedBtn.name)
				{
					btn.selected = false;
				}
			}
		}
	}
	
	public void SetNameLayerOpt(int left, int top, int width, int height, int marginl, int margint, int marginr, int marginb, UTVPFont font, Color color)
	{
		if (m_NameLayer == null)
		{
			m_NameLayer = m_System.CreateMessageLayer<UTVPMessageLayer, UTVPAnimationLayer>("NameLayer", m_Frame, false, 16);
			m_NameLayer.AbsoluteIndex = 50;
			m_NameLayer.Font = this.Font;
			m_NameLayer.CharColor = this.CharColor;
			m_NameLayer.Visible = false;
		}
		m_NameLayer.Frame.SetPosAndSize(left, top, width, height);
		m_NameLayer.MarginLeft = marginl;
		m_NameLayer.MarginTop = margint;
		m_NameLayer.MarginRight = marginr;
		m_NameLayer.MarginBottom = marginb;
		if (font != null)
			m_NameLayer.Font = font;
		if (color != Color.clear)
			m_NameLayer.CharColor = color;
	}
	public void SetNameLayerOpt(int left, int top, UTVPImage img, string seq, int frameIdx, int marginl, int margint, int marginr, int marginb, UTVPFont font, Color color)
	{
		if (m_NameLayer == null)
		{
			m_NameLayer = m_System.CreateMessageLayer<UTVPMessageLayer, UTVPAnimationLayer>("NameLayer", m_Frame, false, 16);
			m_NameLayer.AbsoluteIndex = 50;
			m_NameLayer.Font = this.Font;
			m_NameLayer.CharColor = this.CharColor;
		}
		m_NameLayer.Frame.Image = img;
		m_NameLayer.Frame.SetPos(left, top);
		if (seq == null)
		{
			m_NameLayer.Frame.SetSizeToImageSize();
		}
		else
		{
			UTVPAnimationLayer nameFrame = (UTVPAnimationLayer)m_NameLayer.Frame;
			UTVPAnimFrameInfo frameInfo = img.frameDic[img.sequenceDic[seq].frames[frameIdx]];
			nameFrame.SetSize(frameInfo.w, frameInfo.h);
			nameFrame.SetAnimOption(seq, true, frameIdx, false);
		}
		m_NameLayer.Visible = false;
		m_NameLayer.MarginLeft = marginl;
		m_NameLayer.MarginTop = margint;
		m_NameLayer.MarginRight = marginr;
		m_NameLayer.MarginBottom = marginb;
		if (font != null)
			m_NameLayer.Font = font;
		if (color != Color.clear)
			m_NameLayer.CharColor = color;
	}
	public void SetNameImage(int left, int top, UTVPImage img, string seq, string[] nameList)
	{
		if (m_NameLayer == null)
		{
			m_NameLayer = m_System.CreateMessageLayer<UTVPMessageLayer, UTVPAnimationLayer>("NameLayer", m_Frame, false, 16);
			m_NameLayer.AbsoluteIndex = 50;
			m_NameLayer.Font = this.Font;
			m_NameLayer.CharColor = this.CharColor;
		}
		if (m_NameImgLayer != null)
		{
			m_NameImgLayer = m_System.CreateLayer<UTVPAnimationLayer>("NameImg", m_NameLayer.Frame);
			m_NameImgLayer.AbsoluteIndex = 20;
		}
		m_NameImgLayer.SetPos(left, top);
		m_NameImgLayer.Visible = true;
		m_NameImgLayer.Image = img;
		m_NameImgSeq = seq;
		m_NameList = nameList;
	}
	public void ClearNameImage()
	{
		m_NameImgLayer.Visible = false;
		m_NameList = null;
	}
	public void SetNameLayerOpt(string left, string top, string width, string height,
		string frameImg, string seq, string frameIdx,
		string marginl, string margint, string marginr, string marginb,
		string font, string color)
	{
		if (m_NameLayer == null)
		{
			m_NameLayer = m_System.CreateMessageLayer<UTVPMessageLayer, UTVPAnimationLayer>("NameLayer", m_Frame, false, 16);
			m_NameLayer.AbsoluteIndex = 50;
			m_NameLayer.Font = this.Font;
			m_NameLayer.CharColor = this.CharColor;
		}
		
		UKagSystem system = (UKagSystem)m_System;
		if (left != null || top != null)
		{
			int nameLeft = m_NameLayer.Left;
			int nameTop = m_NameLayer.Top;
			system.Str2Number(left, ref nameLeft);
			system.Str2Number(top, ref nameTop);
			m_NameLayer.Frame.SetPos(nameLeft, nameTop);
		}
		if (width != null || height != null)
		{
			int nameWidth = m_NameLayer.Width;
			int nameHeight = m_NameLayer.Height;
			system.Str2Number(width, ref nameWidth);
			system.Str2Number(height, ref nameHeight);
			m_NameLayer.Frame.SetSize(nameWidth, nameHeight);
		}
		
		system.Str2Number(marginl, ref m_NameLayer.MarginLeft);
		system.Str2Number(margint, ref m_NameLayer.MarginTop);
		system.Str2Number(marginr, ref m_NameLayer.MarginRight);
		system.Str2Number(marginb, ref m_NameLayer.MarginBottom);
		
		if (font != null)
		{
			m_NameLayer.Font = system.Storages.GetFont(font);
		}
		if (color != null)
		{
			m_NameLayer.CharColor = UTVPUtil.StrToColor(color);
		}
		
		if (frameImg != null)
		{
			m_NameLayer.Frame.Image = m_System.Storages.GetImage(frameImg);
			if (seq == null || frameIdx == null)
				m_NameLayer.Frame.SetSizeToImageSize();
		}
		if (seq != null && frameIdx != null)
		{
			int frameIdxInt = 0;
			system.Str2Number(frameIdx, ref frameIdxInt);
			UTVPImage img = m_NameLayer.Frame.Image;
			UTVPAnimationLayer nameFrame = (UTVPAnimationLayer)m_NameLayer.Frame;
			UTVPAnimFrameInfo frameInfo = img.frameDic[img.sequenceDic[seq].frames[frameIdxInt]];
			nameFrame.SetSize(frameInfo.w, frameInfo.h);
			nameFrame.SetAnimOption(seq, true, frameIdxInt, false);
		}
	}
	public void SetNameImage(string left, string top, string nameImg, string nameSeq, string nameList, string clear)
	{
		UKagSystem system = (UKagSystem)m_System;
		if (system.Str2Bool(clear))
		{
			if (m_NameImgLayer != null)
				m_NameImgLayer.Visible = false;
			m_NameList = null;
			return;
		}
		if (nameImg != null && nameSeq != null && nameList != null)
		{
			if (m_NameImgLayer == null)
			{
				m_NameImgLayer = m_System.CreateLayer<UTVPAnimationLayer>("NameImg", m_NameLayer.Frame);
				m_NameImgLayer.AbsoluteIndex = 20;
			}
			if (left != null || top != null)
			{
				int leftInt = m_NameImgLayer.Left;
				int topInt = m_NameImgLayer.Top;
				system.Str2Number(left, ref leftInt);
				system.Str2Number(top, ref topInt);
				m_NameImgLayer.SetPos(leftInt, topInt);
			}
			m_NameImgLayer.Visible = true;
			m_NameImgLayer.Image = m_System.Storages.GetImage(nameImg);;
			m_NameImgSeq = nameSeq;
			m_NameList = nameList.Split(',');
		}
	}
	public void SetName(string text)
	{
		if (m_NameLayer == null)
			return;
		
		if (string.IsNullOrEmpty(text))
		{
			m_NameLayer.ClearContent();
			m_NameLayer.Visible = false;
		}
		else
		{
			if (m_NameList == null || System.Array.IndexOf(m_NameList, text) < 0)
			{
				int textLen = m_NameLayer.GetTextWidth(text);
				m_NameLayer.ClearContent();
				m_NameLayer.SetLocate((m_NameLayer.Width - m_NameLayer.MarginLeft - m_NameLayer.MarginRight - textLen) / 2, 0);
				m_NameLayer.AddText(text);
				m_NameLayer.Visible = true;
				m_NameImgLayer.Visible = false;
			}
			else
			{
				int idx = System.Array.IndexOf(m_NameList, text);
				m_NameLayer.ClearContent();
				UTVPAnimFrameInfo frame = m_NameImgLayer.Image.frameDic[m_NameImgLayer.Image.sequenceDic[m_NameImgSeq].frames[idx]];
				m_NameImgLayer.SetPosAndSize((m_NameLayer.Width - frame.w) / 2, (m_NameLayer.Height - frame.h) / 2, frame.w, frame.h);
				m_NameImgLayer.SetAnimOption(m_NameImgSeq, true, idx, false);
				m_NameImgLayer.Visible = true;
				m_NameLayer.Visible = true;
			}
		}
	}
	public void SetFaceLayerOpt(int left, int top, int width, int height, UTVPImage faceImg)
	{
		if (m_FaceLayer == null)
		{
			m_FaceLayer = m_System.CreateLayer<UTVPAnimationLayer>("FaceLayer", m_Frame);
			m_FaceLayer.AbsoluteIndex = 40;
		}
		m_FaceLayer.Visible = false;
		m_FaceLayer.Image = faceImg;
		m_FaceLayer.SetPosAndSize(left, top, width, height);
	}
	public void SetFaceLayerOpt(string left, string top, string width, string height, string storage)
	{
		int faceLeft = m_FaceLayer.Left;
		int faceTop = m_FaceLayer.Top;
		int faceWidth = m_FaceLayer.Width;
		int faceHeignt = m_FaceLayer.Height;
		
		UKagSystem system = (UKagSystem)m_System;
		system.Str2Number(left, ref faceLeft);
		system.Str2Number(top, ref faceTop);
		system.Str2Number(width, ref faceWidth);
		system.Str2Number(height, ref faceHeignt);
		UTVPImage faceImg = m_System.Storages.GetImage(storage);
		SetFaceLayerOpt(faceLeft, faceTop, faceWidth, faceHeignt, faceImg);
	}
	public void SetFace(string charName, int faceIdx)
	{
		if (m_FaceLayer == null)
			return;
		
		if (string.IsNullOrEmpty(charName))
			m_FaceLayer.Visible = false;
		else
		{
			m_FaceLayer.SetAnimOption(charName, true, faceIdx, false);
			m_FaceLayer.Visible = true;
		}
	}
	public void SetFace(string charName, string faceIdx)
	{
		UKagSystem system = (UKagSystem)m_System;
		int idx = 0;
		if (faceIdx != null)
			system.Str2Number(faceIdx, ref idx);
		SetFace(charName, idx);
	}
	
	public override int ClearContent()
	{
		int result = base.ClearContent();
		
		if (m_NameLayer != null)
			m_NameLayer.Visible = false;
		if (m_FaceLayer != null)
			m_FaceLayer.Visible = false;
		
		ClearControls(false);
		
		return result;
	}
	
	public void SetOptions(string lineBreakMode, string pageBreakMode, string pitch, string lineSpacing,
		string scaleX, string scaleY, string fontFace, string charColor, string shadowColor, string shadow, string edge,
		string marginLeft, string marginTop, string marginRight, string marginBottom,
		string chWaits, string lineWaits, string pageWaits, string visible)
	{
		UKagSystem system = (UKagSystem)m_System;

		if (lineBreakMode != null)
		{
			if (lineBreakMode.ToLower() == "alphabetic")
				this.LineBreakMode = UKagMessageLayer.LINE_BREAK_MODE.Alphabetic;
			else
				this.LineBreakMode = UKagMessageLayer.LINE_BREAK_MODE.CJK;
		}

		if (pageBreakMode != null)
		{
			if (pageBreakMode.ToLower() == "scrollup")
				this.PageBreakMode = UKagMessageLayer.PAGE_BREAK_MODE.ScrollUp;
			else
				this.PageBreakMode = UKagMessageLayer.PAGE_BREAK_MODE.ClearText;
		}

		UTVPFont font = m_Storages.GetFont(fontFace);
		if (font != null)
			this.Font = font;
		if (charColor != null)
			this.CharColor = UTVPUtil.StrToColor(charColor);
		if (shadowColor != null)
			this.ShadowColor = UTVPUtil.StrToColor(shadowColor);
		if (shadow != null || edge != null)
		{
			if (shadow != null && shadow.ToLower() == "true")
				this.Effect = TEXT_EFFECT.Shadow;
			else if (edge != null && edge.ToLower() == "true")
				this.Effect = TEXT_EFFECT.Edge;
			else
				this.Effect = TEXT_EFFECT.None;
		}
		
		system.Str2Number(pitch, ref this.Pitch);
		system.Str2Number(lineSpacing, ref this.LineSpacing);
		system.Str2Number(scaleX, ref this.ScaleX);
		system.Str2Number(scaleY, ref this.ScaleY);
		system.Str2Number(marginLeft, ref this.MarginLeft);
		system.Str2Number(marginTop, ref this.MarginTop);
		system.Str2Number(marginRight, ref this.MarginRight);
		system.Str2Number(marginBottom, ref this.MarginBottom);
		system.Str2Number(chWaits, ref this.ChWaits);
		system.Str2Number(lineWaits, ref this.LineWaits);
		system.Str2Number(pageWaits, ref this.PageWaits);
		
		if (visible != null)
			this.Visible = visible == "true";
	}
	
	public void SetClickGlyphLayerInfo(UTVPImage img, string relineAnim, string repageAnim,
		string fix, string left, string top, string width, string height)
	{
		if (m_ClickGlyphLayer == null)
			return;
		
		UKagSystem system = (UKagSystem)m_System;

		if (img != null)
			m_ClickGlyphLayer.Image = img;
		
		if (relineAnim != null || repageAnim != null)
		{
			if (relineAnim == null)
				relineAnim = repageAnim;
			if (repageAnim == null)
				repageAnim = relineAnim;
			this.m_ClickGlyphLineFeed = relineAnim;
			this.m_ClickGlyphFormFeed = repageAnim;
		}
		
		m_ClickGlyphFix = system.Str2Bool(fix);
		system.Str2Number(left, ref m_ClickGlyphLeft);
		system.Str2Number(top, ref m_ClickGlyphTop);
		m_ClickGlyphLayer.AnimPause = true;
		m_ClickGlyphLayer.Visible = false;
		if (width != null || height != null)
		{
			int widthTemp = m_ClickGlyphLayer.Width;
			system.Str2Number(width, ref widthTemp);
			int heightTemp = m_ClickGlyphLayer.Height;
			system.Str2Number(height, ref heightTemp);
			
			m_ClickGlyphLayer.SetPosAndSize(m_ClickGlyphLeft, m_ClickGlyphTop, widthTemp, heightTemp);
		}
		else if ((left != null || top != null) && m_ClickGlyphFix)
		{
			m_ClickGlyphLayer.SetPos(m_ClickGlyphLeft, m_ClickGlyphTop);
		}
	}

	protected override UTVPMessageLayer_SaveData CreateSaveDataBuff()
	{
		return new UKagMessageLayer_SaveData();
	}
	
	protected override void GetSelfData(UTVPMessageLayer_SaveData dataBuff)
	{
		base.GetSelfData(dataBuff);
		
		UKagMessageLayer_SaveData dataBuffSelf = (UKagMessageLayer_SaveData)dataBuff;
		dataBuffSelf.ChWaits = ChWaits;
		dataBuffSelf.LineWaits = LineWaits;
		dataBuffSelf.PageWaits = PageWaits;
	}
	
	protected override void SetSelfData(UTVPMessageLayer_SaveData dataBuff)
	{
		base.SetSelfData(dataBuff);
		
		UKagMessageLayer_SaveData dataBuffSelf = (UKagMessageLayer_SaveData)dataBuff;
		ChWaits = dataBuffSelf.ChWaits;
		LineWaits = dataBuffSelf.LineWaits;
		PageWaits = dataBuffSelf.PageWaits;
	}
}
